/* -------------------------------------------------------------------
 GeoVISTA Center (Penn State, Dept. of Geography)
 Java source file for the class MapMatrixElement
 Copyright (c), 2002, GeoVISTA Center
 Licensed under Simplified BSD License
 Original Author: Frank Hardisty
 $Author: hardisty $
 $Id: MapMatrixElement.java,v 1.14 2005/08/19 19:17:32 hardisty Exp $
 $Date: 2005/08/19 19:17:32 $
 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
 License as published by the Free Software Foundation; either
 version 2.1 of the License, or (at your option) any later version.
 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 Lesser General Public License for more details.
 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, write to the Free Software
 Foundation, Inc.,
 -------------------------------------------------------------------   */

package edu.psu.geovista.app.map;

import edu.psu.geovista.app.matrix.MatrixElement;
import edu.psu.geovista.app.scatterplot.Histogram;
import edu.psu.geovista.app.scatterplot.ScatterPlot;
import edu.psu.geovista.data.geog.DataSetForApps;
import edu.psu.geovista.symbolization.BivariateColorSymbolClassification;
import edu.psu.geovista.symbolization.BivariateColorSymbolClassificationSimple;
import edu.psu.geovista.symbolization.ColorSymbolizer;
import edu.psu.geovista.ui.cursor.GeoCursors;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;


public class MapMatrixElement extends MapCanvas implements MatrixElement {
  //the following are required for returning to matrix
  private int[] elementPosition;
  private double[] xAxisExtents;
  private double[] yAxisExtents;
  transient private Object[] data;
  transient private DataSetForApps dataSet;
  String attributeX;
  double[] dataX;
  private JToolBar mapTools;
  transient private GeoCursors cursors;

  private Color selectionColor;
        transient private Histogram histogram = new Histogram();

  public MapMatrixElement() {
    super();
    this.autofit = true;
    this.setBorder(BorderFactory.createLineBorder(Color.gray));


    //super.exLabels = null;
    //super.fisheyes = new edu.psu.geovista.ui.Fisheyes();
    super.setMode(MapCanvas.MODE_SELECT);
  }
  public void setSelOriginalColorMode(boolean selOriginalColorMode) {
          //dummy because this is always true in the map. other matrix elements???
  }

  public void setDataObject(Object[] data) {
    this.data = data;
    this.dataSet = new DataSetForApps();
    dataSet.setDataObject(data);
    super.setDataSet(data);
    this.setHistogramData();

    //super.tickleColors();
  }

  public void setElementPosition(int[] dataIndices) {
    this.elementPosition = (int[]) dataIndices.clone();
    //zero based or one based...
    //well...
    //i know...
    //let's keep changing our minds!
    //then we'll never get it straight!
    super.setCurrColorColumnX(this.elementPosition[0]-1);
    super.setCurrColorColumnY(this.elementPosition[1]-1);
    this.setHistogramData();
  }

  public int[] getElementPosition() {
    return this.elementPosition;
  }

  //For axes of scatter plot.
  //a noop for this class
  public void setAxisOn(boolean axisOn) {
  }

  //public void setConditionArray (int[] conditionArray){  }
  //Set min and max for axes. xAxisExtents[0] = min, [1] = max.
  public void setXAxisExtents(double[] xAxisExtents) {
    //histogram.setXAxisExtents(xAxisExtents);
  }

  public void setYAxisExtents(double[] yAxisExtents) {


  }

  public double[] getXAxisExtents() {
    return this.xAxisExtents;
  }

  public double[] getYAxisExtents() {
    return this.yAxisExtents;
  }

  public String getShortDiscription() {
    return "MAP";
  }

  public void setSelectionColor(Color c) {
    this.selectionColor = c;
    super.setColorSelection(c);
  }

  public Color getSelectionColor() {
    return this.selectionColor;
  }

  public void setMultipleSelectionColors(Color[] c) {
  }

  public void setBivarColorClasser(BivariateColorSymbolClassification biColorClasser, boolean reverseColor) {
    if ((biColorClasser == null) || (this.data == null)) {
      return;
    }

    BivariateColorSymbolClassificationSimple biColor =
        (BivariateColorSymbolClassificationSimple) biColorClasser;

    BivariateColorSymbolClassificationSimple biColor2 =
        new BivariateColorSymbolClassificationSimple();
    ColorSymbolizer xSym = biColor.getColorerX();
    ColorSymbolizer ySym = biColor.getColorerY();
    //reverse the color scheme for two variables to compromise the color match between maps and scatterplots in BiPlotMatrix.
        if (reverseColor == true){
                biColor2.setColorerX(ySym);
                biColor2.setColorerY(xSym);
        }else{
                biColor2.setColorerX(xSym);
                biColor2.setColorerY(ySym);
        }
    super.setBivarColorClasser(biColor2);
  }

  public BivariateColorSymbolClassification getBivarColorClasser() {
    return super.bivarColorClasser;
  }

  public void setColorArrayForObs(Color[] colorArrays) {
  }
  private void setHistogramData(){
    if (this.data == null|| this.elementPosition == null){
      return;
    }
    String[] atts = (String[])this.data[0];

    this.attributeX= atts[elementPosition[0]-1];
    int index = this.elementPosition[0];
    //XXX getNumericDataAsDouble has changed...
    dataX = dataSet.getNumericDataAsDouble(index-1);
    double[] extent = histogram.getXAxisExtents();

      extent = new double[2];
      extent[0] = edu.psu.geovista.data.DescriptiveStatistics.min(dataX);
      extent[1] = edu.psu.geovista.data.DescriptiveStatistics.max(dataX);
      this.xAxisExtents = extent;

  }
  private void drawHistogram(Graphics g) {

    Color foreground = Color.white;
    int plotWidth = (int)this.getWidth();
                    int plotHeight = (int)this.getHeight();
                    int size;
                size = (plotWidth < plotHeight) ? plotWidth : plotHeight;

//    //System.out.println("In scatterplot, draw histogram..." + dataIndices[0]);
    histogram.setAxisOn(false);
    histogram.setVariableName(attributeX);
    if (dataX == null){
      this.setHistogramData();
    }
    histogram.setData(dataX);
    histogram.setXAxisExtents(this.xAxisExtents);
    histogram.setBackground(this.getBackground());
    histogram.setSize(this.getWidth(), this.getHeight());


    //histogram.setSelection(this.selRecords);
    if (this.getSelections() != null){
    histogram.setSelections(this.getSelections());
    }
    histogram.paintComponent(g);

    Graphics2D g2 = (Graphics2D) g;
    Color half = new Color(255, 255, 255, 100);
    g2.setColor(half);
    g.fillRect(0, 0, getSize().width, getSize().height);
    g2.setColor(foreground);

    Font font = new Font("", Font.PLAIN, (int) size / 8);
    g.setFont(font);

//    if (attributeX.length() > 12) {
//      g.drawString(attributeX, 2, plotHeight / 2);
//    } else if (attributeX.length() <= 7) {
//      g.drawString(attributeX, plotWidth / 4, plotHeight / 2);
//    } else {
//      g.drawString(attributeX, plotWidth / 8, plotHeight / 2);
//    }

    //font.this.getSize() = (int)plotWidth/12;
    Font font1 = new Font("", Font.PLAIN, (int) size / 12);
    g.setFont(font1);
    g.drawLine(0, 0, 5, 5);

    String maxString = Float.toString((float) (xAxisExtents[1]));
    g.drawString(maxString, 6, (int) (plotHeight * ScatterPlot.AXISSPACEPORTION / 2) + 2);
    g.drawLine(0, plotHeight, 5, plotHeight - 5);

    String minString = Float.toString((float) (xAxisExtents[0]));
    g.drawString(minString, 6, plotHeight - 5);
    g.drawLine(plotWidth, plotHeight, plotWidth - 5, plotHeight - 5);
    g.drawString(maxString,
                 plotWidth - (int) (plotWidth * ScatterPlot.AXISSPACEPORTION + 5),
                 plotHeight - 5);
  }

  /**
   * This method only paints the current contents of the drawingBuff.
   * @param g
   */
  public void paintComponent(Graphics g) {
    if (this.elementPosition == null){
      return;
    }
    if (this.elementPosition[0] != this.elementPosition[1]) {
    super.paintComponent(g);
    }

    if (this.elementPosition == null) {
      return;
    }

    if (this.elementPosition[0] == this.elementPosition[1]) {
      super.paintComponent(g);
      //this.drawHistogram(g);

    }
  }

    public JToolBar getTools(){
      if (mapTools == null) {
        mapTools = new JToolBar();
        //Dimension prefSize = new Dimension(100,10);
        //mapTools.setMinimumSize(prefSize);
        //mapTools.setPreferredSize(prefSize);
        JButton button = null;
        Class cl = this.getClass();
        URL urlGif = null;
        Dimension buttDim = new Dimension(20, 20);

        //first button
        try {
          urlGif = cl.getResource("resources/select16.gif");
          button = new JButton(new ImageIcon(urlGif));
          button.setPreferredSize(buttDim);
        }
        catch (Exception ex) {
          ex.printStackTrace();
        }

        button.setToolTipText("Enter selection mode");
        button.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            MapMatrixElement.this.setCursor(cursors.getCursor(
                GeoCursors.CURSOR_ARROW_SELECT));
            MapMatrixElement.this.setMode(MapCanvas.MODE_SELECT);
          }
        });
        mapTools.add(button);

        mapTools.addSeparator();

        //second button
        try {
          urlGif = cl.getResource("resources/ZoomIn16.gif");
          button = new JButton(new ImageIcon(urlGif));
          button.setPreferredSize(buttDim);
        }
        catch (Exception ex) {
          ex.printStackTrace();
        }

        button.setToolTipText("Enter zoom in mode");
        button.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            MapMatrixElement.this.setCursor(cursors.getCursor(
                GeoCursors.CURSOR_ARROW_ZOOM_IN));
            MapMatrixElement.this.setMode(MapCanvas.MODE_ZOOM_IN);

            //GeoMap.this.setCursor(new Cursor(Cursor.HAND_CURSOR));
          }
        });
        mapTools.add(button);

        //third button
        try {
          urlGif = cl.getResource("resources/ZoomOut16.gif");
          button = new JButton(new ImageIcon(urlGif));
          button.setPreferredSize(buttDim);
        }
        catch (Exception ex) {
          ex.printStackTrace();
        }

        button.setToolTipText("Enter zoom out mode");
        button.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            MapMatrixElement.this.setMode(MapCanvas.MODE_ZOOM_OUT);
            MapMatrixElement.this.setCursor(cursors.getCursor(
                GeoCursors.CURSOR_ARROW_ZOOM_OUT));
          }
        });
        mapTools.add(button);

        //fourth button
        try {
          urlGif = cl.getResource("resources/Home16.gif");
          button = new JButton(new ImageIcon(urlGif));
          button.setPreferredSize(buttDim);
        }
        catch (Exception ex) {
          ex.printStackTrace();
        }

        button.setToolTipText("Zoom to full extent");
        button.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            MapMatrixElement.this.zoomFullExtent();
          }
        });
        mapTools.add(button);

        //fifth button
        try {
          urlGif = cl.getResource("resources/pan16.gif");
          button = new JButton(new ImageIcon(urlGif));
          button.setPreferredSize(buttDim);
        }
        catch (Exception ex) {
          ex.printStackTrace();
        }

        button.setToolTipText("Enter pan mode");
        button.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            MapMatrixElement.this.setCursor(cursors.getCursor(
                GeoCursors.CURSOR_ARROW_PAN));
            MapMatrixElement.this.setMode(MapCanvas.MODE_PAN);
          }
        });
        mapTools.add(button);
        //sixth button
        try {
          urlGif = cl.getResource("resources/excentric16.gif");
          button = new JButton(new ImageIcon(urlGif));
          button.setPreferredSize(buttDim);
        }
        catch (Exception ex) {
          ex.printStackTrace();
        }

        button.setToolTipText("Excentric Labels");
        button.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            MapMatrixElement.this.setCursor(cursors.getCursor(
                GeoCursors.CURSOR_ARROW_PAN));
            MapMatrixElement.this.setMode(MapCanvas.MODE_EXCENTRIC);
          }
        });
        mapTools.add(button);

        //seventh button
        try {
          urlGif = cl.getResource("resources/fisheye16.gif");
          button = new JButton(new ImageIcon(urlGif));
          button.setPreferredSize(buttDim);
        }
        catch (Exception ex) {
          ex.printStackTrace();
        }

        button.setToolTipText("Fisheye Lens");
        button.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            MapMatrixElement.this.setCursor(cursors.getCursor(
                GeoCursors.CURSOR_ARROW_PAN));
            MapMatrixElement.this.setMode(MapCanvas.MODE_FISHEYE);
          }
        });
        mapTools.add(button);
        //eighth button
        try {
          urlGif = cl.getResource("resources/magnifying16.gif");
          button = new JButton(new ImageIcon(urlGif));
          button.setPreferredSize(buttDim);
        }
        catch (Exception ex) {
          ex.printStackTrace();
        }

        button.setToolTipText("Magnifiying Lens");
        button.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            MapMatrixElement.this.setCursor(cursors.getCursor(
                GeoCursors.CURSOR_ARROW_PAN));
            MapMatrixElement.this.setMode(MapCanvas.MODE_PAN);
          }
        });

        mapTools.add(button);
      }
      return mapTools;
    }
  }
